//-----------------------------------------------------------------------

// <copyright file="FilePickerFieldDefinition.cs" company="Jamie Knight">

// Copyright (c) Jamie Knight. All rights reserved.

// </copyright>

//-----------------------------------------------------------------------

using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

namespace DevKnightlie.WPF.AutoForm.FieldDefinitions
{

    /// <summary>
    /// Passed to the FilenameChosen event
    /// </summary>
    public class FilePickerFilenameChosenEventArgs : EventArgs
    {

        public String Filename { get; set; }

        public FilePickerFilenameChosenEventArgs(String filename)
        {
            Filename = filename;
        }

    }

    /// <summary>
    /// Field Definition which creates a text box and associated button for entering filenames
    /// </summary>
    public class FilePickerFieldDefinition : BaseFieldDefinition
    {
        #region Private Fields

        private ICommand _chooseFilenameCommand;
        private TextBox filenameTextBox;
        private Button _chooseButton;
        private bool _commandEnabled = true;
        private bool _textFieldReadOnly = false;
        private string _filenameFilter;
        Binding textBinding;

        #endregion

        #region Properties

        /// <summary>
        /// Sets or returns a value indicating whether the filename text field should be read-only
        /// </summary>
        public bool TextFieldReadOnly
        {
            get { return _textFieldReadOnly; }
            set { _textFieldReadOnly = value; }
        }


        /// <summary>
        /// Sets or returns the Filter string for the FileOpenDialog
        /// </summary>
        public String FilenameFilter
        {
            get { return _filenameFilter; }
            set { _filenameFilter = value; }
        }


        /// <summary>
        /// The command which opens the Select File dialog
        /// </summary>
        public ICommand ChooseFilenameCommand
        {
            get
            {
                if (_chooseFilenameCommand == null)
                {
                    _chooseFilenameCommand = new RoutedCommand();
                }
                return _chooseFilenameCommand;
            }
        }


        public delegate void FilePickerFilenameChosenEvent(object sender, FilePickerFilenameChosenEventArgs e);

        private FilePickerFilenameChosenEvent _filenameChosen;

        /// <summary>
        /// Fired when the user has chosen a filename
        /// </summary>
        public event FilePickerFilenameChosenEvent FilenameChosen
        {
            add { _filenameChosen += value; }
            remove { _filenameChosen -= value; }
        }


        /// <summary>
        /// Returns a reference to the choose file button
        /// </summary>
        public Button ActionButton
        {
            get { return _chooseButton; }
        }

        #endregion

        #region Methods

        public override void BuildInputControl()
        {
            ContentControl result = new ContentControl()
            {
                Focusable = false
            };
            Grid layoutGrid = new Grid()
            {
                HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
                Focusable = false
            };
            layoutGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) });
            layoutGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto) });
            layoutGrid.RowDefinitions.Add(new RowDefinition());
            filenameTextBox = new TextBox()
            {
                VerticalContentAlignment = System.Windows.VerticalAlignment.Center
            };
            _chooseButton = new Button()
            {
                Content = "...",
                Margin = new System.Windows.Thickness(4, 0, 0, 0),
                Padding = new System.Windows.Thickness(8, 4, 8, 4)
            };
            CommandBinding customCommandBinding = new CommandBinding(ChooseFilenameCommand, ExecutedChooseFilenameCommand, CanExecuteChooseFilenameCommand);

            // attach CommandBinding to root window 
            _chooseButton.CommandBindings.Add(customCommandBinding);
            layoutGrid.Children.Add(filenameTextBox);
            layoutGrid.Children.Add(_chooseButton);
            Grid.SetColumn(filenameTextBox, 0);
            Grid.SetRow(filenameTextBox, 0);
            Grid.SetColumn(_chooseButton, 1);
            Grid.SetRow(_chooseButton, 0);
            textBinding = new Binding(PropertyName)
            {
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            BindingOperations.SetBinding(filenameTextBox, TextBox.TextProperty, textBinding);
            SetupEnabledBinding(filenameTextBox);
            SetupEnabledBinding(_chooseButton);
            result.Content = layoutGrid;
            InputControl = filenameTextBox;
            ContainerControl = result;
        }



        private void CanExecuteChooseFilenameCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _commandEnabled;
        }


        private void ExecutedChooseFilenameCommand(object sender, ExecutedRoutedEventArgs e)
        {
            ChooseFilename();
        }


        /// <summary>
        /// Displays a Win32 Open File Dialog and sets the text box to the chosen filename
        /// </summary>
        public void ChooseFilename()
        {
            _commandEnabled = false;
            try
            {
                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog()
                {
                    FileName = filenameTextBox.Text,
                    Filter = FilenameFilter
                };
                bool? result = dlg.ShowDialog();
                if (result.HasValue && result.Value)
                {
                    filenameTextBox.Text = dlg.FileName;
                    if (_filenameChosen != null)
                    {
                        FilePickerFilenameChosenEventArgs e = new FilePickerFilenameChosenEventArgs(dlg.FileName);
                        _filenameChosen(this, e);
                        filenameTextBox.Text = e.Filename; // In case the handler changed it
                    }
                }
            }
            finally
            {
                _commandEnabled = true;
            }
        }

        #endregion


    }
}
